#include "includes.h"

static PS_MODULE pstModule_list;


static PS_MODULE module_add_list(PS_MODULE pstHead, PS_MODULE pstAdd)
{
	PS_MODULE *ppstTemp;
	
	if (pstHead == NULL)
	{
		pstHead = pstAdd;
		pstHead->pnext = NULL;
		return pstHead;
	}

	ppstTemp = &pstHead->pnext;
	while (*ppstTemp)
	{
		ppstTemp = &(*ppstTemp)->pnext;
	}
	*ppstTemp = pstAdd;
	pstAdd->pnext = NULL;
	return pstHead;
}


PS_MODULE module_create(char *name, int prio)
{
	PS_MODULE pst;
	pst = Malloc(sizeof(S_MODULE));
	bzero(pst, sizeof(S_MODULE));
	strncpy(pst->module_name, name, 20);

	if (prio != MODULE_PRIO_IGNORE)
	{
		pst->module_prio = prio;
		pst->module_stat = MODULE_STAT_READY;
		pstModule_list = module_add_list(pstModule_list, pst);
	}
	return pst;
}


int module_register_gui(PS_MODULE self, DLGTEMPLATE *pstDlg, CTRLDATA *pstCtr, int cnt, WNDPROC proc)
{
	PS_PROP_LIST pstList;
	pstDlg->controls = pstCtr;
	pstDlg->controlnr = cnt;
	pstList = Malloc(sizeof(S_PROP_LIST));
	bzero(pstList, sizeof(S_PROP_LIST));
	if (self)
		self->pstConf_gui = pstList;
	pstList->pstDlg = pstDlg;
	pstList->cbProc = proc;
	pstList->pnext = NULL;
	add_conf_list(pstList);
	return 0;
}


int local_register_gui(DLGTEMPLATE *pstDlg, CTRLDATA *pstCtr, int cnt, WNDPROC proc)
{
	PS_PROP_LIST pstList;
	pstDlg->controls = pstCtr;
	pstDlg->controlnr = cnt;
	pstList = Malloc(sizeof(S_PROP_LIST));
	bzero(pstList, sizeof(S_PROP_LIST));
	pstList->pstDlg = pstDlg;
	pstList->cbProc = proc;
	pstList->pnext = NULL;
	add_manu_list(pstList);
	return 0;
}

int module_register_configure(PS_MODULE self, MOMAP_PS pstMap, int cnt)
{
	ELEMENT_PS pstUnit;
	pstUnit = Malloc(sizeof(ELEMENT_S));
	bzero(pstUnit, sizeof(ELEMENT_S));
	self->pstConf_unit = pstUnit;
	strncpy(pstUnit->name, self->module_name, 20);
	pstUnit->count = cnt;
	pstUnit->pstMap = pstMap;
	add_configure(pstUnit);
	if (self->module_prio == MODULE_PRIO_IGNORE)
		free(self);
	return 0;
}


int module_install_oper(PS_MODULE self, PS_TASK_OPERATE pstOper)
{
	if (pstOper)
		self->pstOperate = pstOper;
	else
		return -1;
	return 0;
}

static int module_deal(PS_MODULE self)
{
	PS_TASK_OPERATE pstOp;
	int ret; 
	pstOp = self->pstOperate;
	if (!pstOp)
		return -1;
		
	if (pstOp->task_init)
	{
		if ((*pstOp->task_init)(self) == -1)
			return -1;
	}

	set_run_stat_name(self->module_name);
	if (pstOp->task_deal)
		ret = (*pstOp->task_deal)(self);
	
	if (ret == 0)
	{
		if (pstOp->task_end)
			(*pstOp->task_end)(self);
	}
	else
	{
		if (pstOp->task_err)
			(*pstOp->task_err)(self);
		return -1;
	}
	
	return 0;
}

void *module_schedul(void *ptr)
{
	PS_MODULE pstModule, pstNode;
	int prio;
	int ret;
	//printf("schedul \n");
	//printf("the pthread id is %lu\n", pthread_self());
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
	pstModule = pstModule_list;
	while (pstModule)
	{
		pstModule->module_stat = MODULE_STAT_READY;
		pstModule = pstModule->pnext;
	}
	
	if (pstModule_list)
	{
		do
		{
			pstNode = NULL;
			pstModule = pstModule_list;
			prio = MODULE_PRIO_IGNORE;
			while (pstModule)
			{
				if (pstModule->module_stat==MODULE_STAT_READY && pstModule->module_prio<prio)
				{
					prio = pstModule->module_prio;
					pstNode = pstModule;
				}
				pstModule = pstModule->pnext;
			}

			if (pstNode)
			{
				//printf("find the node\n");
				//set_run_stat_name(pstNode->module_name);
				ret = module_deal(pstNode);
				if (ret == -1)
					return 0;
				pstNode->module_stat = MODULE_STAT_FINISH;
			}
		}while(pstNode);
	}
	return 0;
}
